import random
import time

import pytest
import requests
import json
from unittest.mock import patch, MagicMock

# 配置信息
API_URL = "https://cvm.tencentcloudapi.com/"
REGION = "ap-guangzhou"
SECRET_ID = "your-secret-id"
SECRET_KEY = "your-secret-key"


def generate_signature(params, secret_key):
    """生成签名（模拟实现）"""
    return "mock-signature"


def send_request(action, params):
    """发送API请求（模拟实现）"""
    common_params = {
        "Action": action,
        "Version": "2017-03-12",
        "Region": REGION,
        "SecretId": SECRET_ID,
        "Timestamp": int(time.time()),
        "Nonce": random.randint(1, 1000000),
        "SignatureMethod": "HmacSHA256"
    }
    all_params = {**common_params, **params}
    all_params["Signature"] = generate_signature(all_params, SECRET_KEY)

    response = requests.post(API_URL, data=all_params)
    return response.json()


class TestInquiryInstanceRefund:
    @patch('requests.post')
    def test_inquiry_success(self, mock_post):
        """测试成功询价"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "RequestId": "1234567890",
                "RefundAmount": 100.50,
                "Currency": "CNY",
                "Detail": "退还计算费用"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceId": "ins-valid-id"}
        result = send_request("InquiryInstanceRefund", params)

        assert "Response" in result
        assert "RefundAmount" in result["Response"]

    @patch('requests.post')
    def test_inquiry_price_failed(self, mock_post):
        """测试查询退还价格失败"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "FailedOperation.InquiryRefundPriceFailed",
                    "Message": "查询退换价格失败，找不到付款订单"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("InquiryInstanceRefund", {"InstanceId": "ins-expired"})
        assert result["Response"]["Error"]["Code"] == "FailedOperation.InquiryRefundPriceFailed"

    @patch('requests.post')
    def test_unreturnable_instance(self, mock_post):
        """测试实例无法退还"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "FailedOperation.Unreturnable",
                    "Message": "实例无法退还"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("InquiryInstanceRefund", {"InstanceId": "ins-unreturnable"})
        assert result["Response"]["Error"]["Code"] == "FailedOperation.Unreturnable"

    @patch('requests.post')
    def test_internal_trade_error(self, mock_post):
        """测试交易内部错误"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InternalError.TradeUnknownError",
                    "Message": "内部错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("InquiryInstanceRefund", {"InstanceId": "ins-valid-id"})
        assert result["Response"]["Error"]["Code"] == "InternalError.TradeUnknownError"

    @patch('requests.post')
    def test_internal_server_error(self, mock_post):
        """测试内部服务器错误"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InternalServerError",
                    "Message": "操作内部错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("InquiryInstanceRefund", {"InstanceId": "ins-valid-id"})
        assert result["Response"]["Error"]["Code"] == "InternalServerError"

    @patch('requests.post')
    def test_unsupported_instance(self, mock_post):
        """测试不支持的实例"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstance.NotSupported",
                    "Message": "不被支持的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("InquiryInstanceRefund", {"InstanceId": "ins-unsupported"})
        assert result["Response"]["Error"]["Code"] == "InvalidInstance.NotSupported"

    @patch('requests.post')
    def test_malformed_instance_id(self, mock_post):
        """测试无效格式的实例ID"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstanceId.Malformed",
                    "Message": "无效实例ID格式"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("InquiryInstanceRefund", {"InstanceId": "invalid-format"})
        assert result["Response"]["Error"]["Code"] == "InvalidInstanceId.Malformed"

    @patch('requests.post')
    def test_instance_not_found(self, mock_post):
        """测试实例不存在"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstanceId.NotFound",
                    "Message": "实例不存在"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("InquiryInstanceRefund", {"InstanceId": "ins-not-found"})
        assert result["Response"]["Error"]["Code"] == "InvalidInstanceId.NotFound"

    @patch('requests.post')
    def test_invalid_prepaid_instance(self, mock_post):
        """测试不满足包月退还规则的实例"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstanceNotSupportedPrepaidInstance",
                    "Message": "该实例不满足包月退还规则"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("InquiryInstanceRefund", {"InstanceId": "ins-not-prepaid"})
        assert result["Response"]["Error"]["Code"] == "InvalidInstanceNotSupportedPrepaidInstance"

    @patch('requests.post')
    def test_invalid_parameter_value(self, mock_post):
        """测试参数取值错误"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue",
                    "Message": "参数取值错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceId": "ins-valid-id", "InvalidParam": "invalid"}
        result = send_request("InquiryInstanceRefund", params)
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue"

    @patch('requests.post')
    def test_instance_id_format_error(self, mock_post):
        """测试实例ID格式不符合要求"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue.InstanceIdMalformed",
                    "Message": "实例ID格式错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("InquiryInstanceRefund", {"InstanceId": "INS-VALID-ID"})
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue.InstanceIdMalformed"

    @patch('requests.post')
    def test_parameter_limit_exceeded(self, mock_post):
        """测试参数值数量超过限制"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue.LimitExceeded",
                    "Message": "参数值数量超过限制"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceId": ["ins-1", "ins-2"] * 100}  # 假设限制为50个
        result = send_request("InquiryInstanceRefund", params)
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue.LimitExceeded"

    @patch('requests.post')
    def test_missing_parameter(self, mock_post):
        """测试缺少必要参数"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "MissingParameter",
                    "Message": "缺少参数错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("InquiryInstanceRefund", {})
        assert result["Response"]["Error"]["Code"] == "MissingParameter"

    @patch('requests.post')
    def test_mixed_pricing_model(self, mock_post):
        """测试不支持混合付费模式"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceMixedPricingModel",
                    "Message": "不支持混合付费模式"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("InquiryInstanceRefund", {"InstanceId": "ins-mixed-pricing"})
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceMixedPricingModel"

    @patch('requests.post')
    def test_mixed_zone_type(self, mock_post):
        """测试不支持混合可用区类型"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceMixedZoneType",
                    "Message": "中心可用区和边缘可用区实例不能混用批量操作"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceId": ["ins-center", "ins-edge"]}
        result = send_request("InquiryInstanceRefund", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceMixedZoneType"

    @patch('requests.post')
    def test_banned_instance(self, mock_post):
        """测试封禁状态的实例"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateBanning",
                    "Message": "该子机处于封禁状态"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("InquiryInstanceRefund", {"InstanceId": "ins-banned"})
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateBanning"

    @patch('requests.post')
    def test_unsupported_region(self, mock_post):
        """测试不支持的地域"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.Region",
                    "Message": "不支持该地域"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("InquiryInstanceRefund", {"InstanceId": "ins-unsupported-region"})
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.Region"

    @patch('requests.post')
    def test_permission_denied(self, mock_post):
        """测试权限不足"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "AuthFailure.UnauthorizedOperation",
                    "Message": "权限不足"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("InquiryInstanceRefund", {"InstanceId": "ins-valid-id"})
        assert result["Response"]["Error"]["Code"] == "AuthFailure.UnauthorizedOperation"


# 启动测试函数
def run_tests():
    pytest.main([__file__, "-v", "-s"])


if __name__ == "__main__":
    run_tests()